<template>
    <div class="player-container">
        <!-- 左侧唱片动画 -->
        <div class="disc-container">
            <div class="disc" :class="{ 'disc-playing': isPlaying }">
                <!-- 唱针 -->
                <div class="stylus" :class="{ 'stylus-playing': isPlaying }">
                    <img src="@/assets/img/stylus.png" alt="stylus">
                </div>
                <!-- 唱片 -->
                <div class="disc-plate">
                    <img class="disc-bg" src="@/assets/img/disc_bg.png" alt="disc">
                    <img class="album-cover" :src="albumCover" alt="cover">
                </div>
            </div>
        </div>

        <!-- 右侧歌词 -->
        <div class="lyrics-container">
            <div class="lyrics-main" :style="{maxHeight: maxH + 'px'}">
                <div class="lyrics" ref="lyrics" v-if="lyricObj.length" :style="transform">
                    <p :class="[isCurLyric(index)]" v-for="(item, index) in lyricObj" :key="index">{{item.txt}}</p>
                </div>
                <div v-else class="lyric-empty">
                    <p v-if="lyric">纯音乐，无歌词</p>
                    <p v-else>歌词加载中......</p>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { reactive, computed, onMounted, watch, toRefs } from 'vue';
import apis from '@/assets/apis/instance';

// Props
const props = defineProps({
  sId: {
    type: [Number, String],
    default: 0
  },
  currentTime: {
    type: Number,
    default: 0
  },
  maxH: {
    type: [Number, String],
    default: 390
  },
  isPlaying: {
    type: Boolean,
    default: false
  },
  albumCover: {
    type: String,
    default: ''
  }
});

// Reactive state
const info = reactive({
  lyric: null,
  lyricObj: [],
  curIndex: 0,
  isFull: false
});


// Computed properties
const isCurLyric = computed(() => {
  return (index) => {
    return index === info.curIndex && props.currentTime ? 'active' : '';
  };
});

const transform = computed(() => {
  return info.curIndex > 6 ? `transform: translateY(-${30 * (info.curIndex - 6)}px)` : 'transform: translateY(0)';
});

// Methods
async function getLyrics (id)  {
  const { lrc } = await apis.get("/lyric?id="+id)
  //console.log(id+"获取歌词信息",lrc)
  formatLyric(lrc);
}

const formatLyric = (lrc) => {
  const lrcReg = /^\[(\d{2}):(\d{2}.\d{2,})\]\s*(.+)$/;

  if (!lrc.lyric) {
    info.lyric = true;
    return;
  }

  const lyricLis = lrc.lyric.split('\n');
  info.lyric = lrc.lyric;

  lyricLis.forEach(item => {
    const arr = lrcReg.exec(item);
    if (!arr) return;

    info.lyricObj.push({ t: arr[1] * 60 + +arr[2], txt: arr[3] });
  });

  // 根据时间轴重排顺序
  info.lyricObj.sort((a, b) => a.t - b.t);
};

const findCurIndex = (t) => {
  for (let i = 0; i < info.lyricObj.length; i++) {
    if (t <= info.lyricObj[i].t) {
      return i;
    }
  }
  return info.lyricObj.length;
};

// 页面歌词可以展开查看更多
const fullLyric = () => {
  info.isFull = !info.isFull;
};

// Lifecycle hooks
onMounted(() => {
  getLyrics(props.sId);
});

watch(() => props.sId, (newVal) => {
  info.lyric = null;
  info.lyricObj = [];
  info.curIndex = 0;
  getLyrics(newVal);
});

watch(() => props.currentTime, (newVal) => {
  // 无歌词的时候不做动画滚动
  if (!info.lyricObj.length) return;
  info.curIndex = findCurIndex(newVal) - 1;
});

// Expose to template
const { lyric, lyricObj, curIndex, isFull } = toRefs(info);
</script>
<style scoped lang="scss">
.player-container {
  display: flex;
  padding: 20px;
  height: 100%;
  
  .disc-container {
    flex: 0 0 400px;
    position: relative;
    
    .disc {
      width: 100%;
      padding-top: 60px;
      
      &.disc-playing {
        .disc-plate {
          animation: rotate 20s linear infinite;
        }
      }
      
      .stylus {
        position: absolute;
        top: 0;
        left: 50%;
        width: 100px;
        height: 200px;
        transform-origin: 15px 15px;
        transform: rotate(-30deg);
        transition: transform 0.3s ease-in-out;
        z-index: 1;
        
        &.stylus-playing {
          transform: rotate(0deg);
        }
        
        img {
          width: 100%;
        }
      }
      
      .disc-plate {
        position: relative;
        width: 300px;
        height: 300px;
        margin: 0 auto;
        animation-play-state: paused;
        
        .disc-bg {
          position: absolute;
          width: 100%;
          height: 100%;
        }
        
        .album-cover {
          position: absolute;
          top: 50%;
          left: 50%;
          width: 190px;
          height: 190px;
          transform: translate(-50%, -50%);
          border-radius: 50%;
        }
      }
    }
  }
  
  .lyrics-container {
    flex: 1;
    margin-left: 40px;
    overflow: hidden;
  }
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.lyrics-main {
    height: 100%;
    overflow-y: auto;
    transition: all 1.5s ease-in-out;
}

.lyrics {
    font-size: 0;
    transform: translateY(0);
    transition: transform 1.5s ease-in-out;

    :deep(p) {
        margin: 0;
        line-height: 30px;
        font-size: 14px;
        font-weight: 300;

        &.active {
            color: var(--color-text-height);
        }
    }
}
.lyric-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    min-height: 100px;
    font-size: 14px;
    color: var(--color-text-height);

    ~ .more-lyric {
        display: none;
    }
}
.page-lyrics {
    color: #666;
    overflow: hidden;

    .lyric-empty {
        justify-content: left;
    }

    &.fullLyrics {
        max-height: none;
    }
}

.lyric-more span {
    display: inline-block;
    line-height: 30px;
    cursor: pointer;
    color: var(--color-text-height);
}
</style>
